package com.qh.pay.service.impl;

import com.qh.pay.api.PayApi;
import com.qh.pay.exrick.bean.Pay;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

import com.qh.common.config.Constant;
import com.qh.common.utils.R;
import com.qh.pay.dao.PayQrConfigDao;
import com.qh.pay.domain.PayAcctBal;
import com.qh.pay.domain.PayQrConfigDO;
import com.qh.pay.service.MerchantService;
import com.qh.pay.service.PayQrConfigService;
import com.qh.redis.RedisConstants;
import com.qh.redis.service.RedisUtil;


@Service
public class PayQrConfigServiceImpl implements PayQrConfigService {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(PayQrConfigServiceImpl.class);

    @Autowired
    private PayQrConfigDao payQrConfigDao;

    @Autowired
    private MerchantService merchantService;

    @Override
    public PayQrConfigDO get(Integer id) {
        return payQrConfigDao.get(id);
    }

    @Override
    public List<PayQrConfigDO> list(Map<String, Object> map) {

        return payQrConfigDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return payQrConfigDao.count(map);
    }

    @Override
    public int save(PayQrConfigDO payQrConfig) {
        PayQrConfigDO payQrCfg = this.getCacheQrs(payQrConfig);
        if (payQrCfg != null) {
            logger.warn("改通道配置已经存在{}，{}, {}", payQrConfig.getOutChannel(), payQrConfig.getAccountNo());
            return Constant.data_exist;
        }
        payQrConfig.setUseStatus(1);

        int count = payQrConfigDao.save(payQrConfig);
        if (count > 0) {
            RedisUtil.updateMonAmountNum(payQrConfig.getOutChannel(),String.valueOf(payQrConfig.getMoney()),true);
//            this.putCacheQrs(payQrConfig);
        }
        return count;
    }

    @Override
    public int update(PayQrConfigDO payQrConfig) {

        payQrConfig.setEndDate( LocalDateTime.now().plusHours(payQrConfig.getStatus()));
        int count = payQrConfigDao.updateByCode(payQrConfig);
//        if (count > 0) {
//            payQrConfig.setQrs(payQrConfig.getQrs());
//            this.putCacheQrs(payQrConfig);
//        }
        return count;
    }
    @Override
    public int updateQrState(String status, String accountNo, String outChannel ) {
        int count = payQrConfigDao.updateQrState(status,accountNo,outChannel);
        return count;
    }

    @Override
    public int updatePayState(String status, String accountNo, String outChannel ) {
        int count = payQrConfigDao.updateQrPayState(status,accountNo,outChannel);
        return count;
    }
    @Override
    public int updateQrUseState(String status, String accountNo, String outChannel,String mount ) {
        int count = payQrConfigDao.updateQrUseState(status,accountNo,outChannel);
        if(count>0){
            if(status.equals("1")){
                RedisUtil.updateMonAmountNum(outChannel,mount,true);
            }else{
                RedisUtil.updateMonAmountNum(outChannel,mount,false);
            }
        }
        return count;
    }

    @Override
    public int updateQrPayState(String status, String accountNo, String outChannel) {
        int count = payQrConfigDao.updateQrPayState(status,accountNo,outChannel);

        return count;
    }
    @Override
    public int updateQrs(PayQrConfigDO payQrConfig) {
        int count = payQrConfigDao.updateQr(payQrConfig);
        if (count > 0) {
            payQrConfig.setQrs(this.getCacheQrs(payQrConfig).getQrs());
            this.putCacheQrs(payQrConfig);
        }
        return count;
    }

    @Override
    public int remove(String id) {
//        this.delCacheQrs(outChannel, accountNo);
       PayQrConfigDO payQrConfigDO =  payQrConfigDao.get(Integer.parseInt(id));
        int i = payQrConfigDao.remove(id);
        if(i==1){
         if(payQrConfigDO.getPayStatus()==0&&payQrConfigDO.getUseStatus()==1){
             RedisUtil.updateMonAmountNum(payQrConfigDO.getOutChannel(),String.valueOf(payQrConfigDO.getMoney()),false);
         }
        }
        return i;
    }
    @Override
    public int updatePay(String id) {
        PayQrConfigDO payQrConfigDO = payQrConfigDao.get(Integer.parseInt(id));
        if(payQrConfigDO.getPayStatus()==1){
        return -1;
        }
       int i =  PayApi.pay(payQrConfigDO);
       if(i==1){
//           payQrConfigDao.updateQrPayState("0",payQrConfigDO.getAccountNo(),payQrConfigDO.getOutChannel());
       }else if(i==2){
           payQrConfigDao.updateQrPayState("1",payQrConfigDO.getAccountNo(),payQrConfigDO.getOutChannel());
           new RedisUtil().paystatus( payQrConfigDO);
       }else{
           payQrConfigDao.updateQrPayState("2",payQrConfigDO.getAccountNo(),payQrConfigDO.getOutChannel());
       }
       return 1;
    }
    @Override
    public int removeAll() {
//        this.delCacheQrs(outChannel, accountNo);
        return payQrConfigDao.removeAll();
    }
    /* (非 Javadoc)
     * Description:
     * @see com.qh.pay.service.PayQrConfigService#get(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public PayQrConfigDO get(String outChannel, String accountNo) {
//        PayQrConfigDO payQrCfg = getCacheQrs(outChannel, accountNo);
//        if (payQrCfg == null) {
            PayQrConfigDO   payQrCfg = payQrConfigDao.getByCode(outChannel, accountNo);
            if (payQrCfg != null) {
                this.putCacheQrs(payQrCfg);
            }
//        }
        return payQrCfg;
    }

    /* (非 Javadoc)
     * Description:
     * @see com.qh.pay.service.PayQrConfigService#updateQrs(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public R updateQrs(String outChannel, String accountNo, String moneyAmount) {
        //支付二维码扫码图片
        PayQrConfigDO payQrCfg = this.get(outChannel, accountNo);
        if (payQrCfg == null) {
            return R.error("该商户通道不存在");
        }
//		if(payQrCfg.getQrs() == null){
//			payQrCfg.setQrs(new HashMap<>());
//		}
//		if(payQrCfg.getQrs().get(moneyAmount) != null){
//			return R.error("该付款码金额已经存在");
//		}
//		payQrCfg.getQrs().put(moneyAmount, 1);
//		int count = payQrConfigDao.updateQrs(outChannel,accountNo,payQrCfg.getQrs());
//		if(count > 0){
//			this.putCacheQrs(payQrCfg);
//		}
        return R.ok("处理成功").put("fileName", moneyAmount);
    }

    /* (非 Javadoc)
     * Description:
     * @see com.qh.pay.service.PayQrConfigService#removeQrs(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public R removeQrs(String outChannel, String accountNo, String moneyAmount) {
        //支付二维码扫码图片
        PayQrConfigDO payQrCfg = this.get(outChannel, accountNo);
//		if(payQrCfg.getQrs()!=null){
//			payQrCfg.getQrs().remove(moneyAmount);
//		}else{
//			return R.error("二维码收款图片不存在");
//		}
//		int count = payQrConfigDao.updateQrs(outChannel,accountNo,payQrCfg.getQrs());
//		if(count > 0){
//			this.putCacheQrs(payQrCfg);
//		}else{
//			return R.error("删除失败");
//		}
        return R.ok("处理成功");
    }

    @Override
    public R removeQrs(String outChannel, String accountNo, List<String> moneyAmounts) {
        //支付二维码扫码图片
        PayQrConfigDO payQrCfg = this.get(outChannel, accountNo);
        if (payQrCfg.getQrs() != null) {
            for (String moneyAmount : moneyAmounts) {
//				payQrCfg.getQrs().remove(moneyAmount);
            }
        } else {
            return R.error("二维码收款图片不存在");
        }
//		int count = payQrConfigDao.updateQrs(outChannel,accountNo,payQrCfg.getQrs());
//		if(count > 0){
//			this.putCacheQrs(payQrCfg);
//		}else{
//			return R.error("删除失败");
//		}
        return R.ok("处理成功");
    }

    @Override
    public Set<Object> findAccountNo(String outChannel) {
        return RedisUtil.getRedisTemplate().opsForHash().keys(RedisConstants.cache_qrs +
                outChannel);
    }


    private void putCacheQrs(String outChannel, String accountNo, PayQrConfigDO payQrCfg) {
        if (RedisUtil.getRedisTemplate().opsForHash().hasKey(RedisConstants.cache_qrs +
                outChannel + RedisConstants.link_symbol + accountNo, RedisConstants.cache_qrs +
                outChannel + RedisConstants.link_symbol + accountNo)) {
            RedisUtil.getRedisTemplate().opsForHash().delete(RedisConstants.cache_qrs +
                    outChannel + RedisConstants.link_symbol + accountNo, RedisConstants.cache_qrs +
                    outChannel + RedisConstants.link_symbol + accountNo);
        }
        RedisUtil.getRedisTemplate().opsForHash().put(RedisConstants.cache_qrs +
                outChannel + RedisConstants.link_symbol + accountNo, accountNo, payQrCfg);

    }

    private void putCacheQrs(PayQrConfigDO payQrCfg) {
        putCacheQrs(payQrCfg.getOutChannel(), payQrCfg.getAccountNo(), payQrCfg);
    }

    private PayQrConfigDO getCacheQrs(PayQrConfigDO payQrCfg) {
        return getCacheQrs(payQrCfg.getOutChannel(), payQrCfg.getAccountNo());
    }

    private PayQrConfigDO getCacheQrs(String outChannel, String accountNo) {
        return (PayQrConfigDO) RedisUtil.getRedisTemplate().opsForHash().get(RedisConstants.cache_qrs +
                outChannel + RedisConstants.link_symbol, accountNo);
    }

    private void delCacheQrs(String outChannel, String accountNo) {
        RedisUtil.getRedisTemplate().opsForHash().delete(RedisConstants.cache_qrs +
                outChannel + RedisConstants.link_symbol, accountNo);
    }

    private void delCacheQrs(PayQrConfigDO payQrCfg) {
        delCacheQrs(payQrCfg.getOutChannel(), payQrCfg.getAccountNo());
    }
}


